import BaseView from '../BaseView';
import utils from '../../utils';


export default class TextView extends BaseView {
    private text = '';
    private color = '#000000';
    private fontFamily = 'miui, Arial, Microsoft YaHei, 黑体, 宋体, sans-serif';
    private fontSize = 14;
    private indent = 0;
    private ellipsis = false;
    private line = 1;
    private textAlign: 'left' | 'center' | 'right' = 'left';
    private verticalAlign: "bottom" | "middle" | "top" = 'top';
    private underline = false;

    private texts: Array<{
        text: string;
        x: number;
        y: number
    }> = [];

    public setText(text: string) {
        this.text = text + '';
    }

    public getText() {
        return this.text;
    }

    public setColor(color: string) {
        this.color = color;
    }
    public getColor() {
        return this.color;
    }


    public setFontFamily(fontFamily: string) {
        this.fontFamily = fontFamily;
    }

    public getFontFamily() {
        return this.fontFamily;
    }

    public setFontSize(fontSize: number) {
        this.fontSize = fontSize;
        if (this.getHeight() === 0) {
            this.setHeight(fontSize);
        }
    }

    public getFontSize() {
        return this.fontSize;
    }

    public getIndent() {
        return this.indent;
    }
    public setIndent(indent: number) {
        this.indent = indent;
    }

    public getEllipsis() {
        return this.ellipsis;
    }
    public setEllipsis(ellipsis: boolean) {
        this.ellipsis = ellipsis;
    }
    public getLine() {
        return this.line;
    }
    public setLine(line: number) {
        this.line = line;
    }
    public getTextAlign() {
        return this.textAlign;
    }
    public setTextAlign(textAlign: 'left' | 'center' | 'right') {
        this.textAlign = textAlign;
    }

    public getVerticalAlign() {
        return this.verticalAlign;
    }

    public setVerticalAlign(verticalAlign: "bottom" | "middle" | "top") {
        this.verticalAlign = verticalAlign;
    }

    public getUnderline() {
        return this.underline;
    }

    public setUnderline(underline: boolean) {
        return this.underline = underline;
    }

    public getDrawFontSize() {
        return utils.getScaleRatioSize(this.getFontSize());
    }

    public getDrawIndent() {
        return utils.getScaleRatioSize(this.getIndent());
    }

    public dimensions(ctx: CanvasRenderingContext2D) {
        ctx.font = `${this.getDrawFontSize()}px ${this.getFontFamily()}`;
        ctx.fillStyle = this.getColor();
        ctx.textBaseline = this.getVerticalAlign();
        ctx.textAlign = this.getTextAlign();
        if (this.width === 0 && this.text.length > 0) {
            let w = Math.ceil(utils.getScaleMinRatioSize(ctx.measureText(this.text).width) + this.getIndent());
            if (w > super.getWidth()) {
                w = super.getWidth();
            }
            this.setWidth(w);
        }

    }

    public async draw(ctx: CanvasRenderingContext2D) {
        this.texts = this.getCutTexts(ctx);
        const lineHeight = this.getDrawHeight() / this.getLine();
        this.texts.forEach((item) => {
            let x = item.x;
            let y = item.y;
            if (this.getTextAlign() === 'center') {
                x = this.getDrawX() + this.getDrawWidth() / 2;
            } else if (this.getTextAlign() === 'right') {
                x = this.getDrawX() + this.getDrawWidth();
            }
            if (this.getVerticalAlign() === 'top') {

            } else if (this.getVerticalAlign() === 'middle') {
                y += lineHeight / 2;
            } else if (this.getVerticalAlign() === 'bottom') {
                y += lineHeight;

            }
            ctx.fillText(item.text, x, y);
        });
        if (this.underline) {
            this.drawUnderline(ctx);
        }
        super.draw(ctx);
    }

    public getCutTexts(ctx: CanvasRenderingContext2D) {
        let lineWidth = 0;
        let lastIndex = 0;
        let y = this.getDrawY();
        const text = this.getText();
        const len = text.length;
        const dtexts: Array<{ text: string, x: number, y: number }> = [];
        const ellipsis = this.getEllipsis();
        const lineHeight = this.getDrawHeight() / this.getLine();
        for (let i = 0; i < len; i++) {
            if (ellipsis && dtexts.length >= this.getLine()) {
                const lastText = dtexts[dtexts.length - 1];
                lastText.text = lastText.text.substr(0, lastText.text.length - 2) + '...';
                break;
            }
            const indent = dtexts.length === 0 ? this.getDrawIndent() : 0;
            let drawWidth = Math.ceil(this.getDrawWidth());
            if (indent > 0) {
                drawWidth -= indent;
            }
            const info = ctx.measureText(text[i]);
            lineWidth += Math.floor(info.width);

            if (lineWidth > drawWidth) {
                const dt = text.substring(lastIndex, i);
                dtexts.push({
                    text: dt,
                    x: this.getDrawX() + indent,
                    y
                });
                lastIndex = i;
                lineWidth = 0;
                y += lineHeight;
                i--;
            } else {
                if (i === len - 1) {
                    const dt = text.substring(lastIndex, len);
                    dtexts.push({
                        text: dt,
                        x: this.getDrawX() + indent,
                        y
                    });
                }
            }
        }


        return dtexts;

    }

    private drawUnderline(ctx: CanvasRenderingContext2D) {
        ctx.strokeStyle = this.getColor();
        const lineHeight = this.getDrawHeight() / this.getLine();
        this.texts.map((item) => {
            const y = item.y + lineHeight / 2;
            ctx.beginPath();
            ctx.textBaseline = this.getVerticalAlign();
            ctx.moveTo(item.x, y);
            ctx.lineTo(item.x + this.getDrawWidth(), y);
            ctx.stroke();
        });
    }

}
